pub mod utils;
pub mod events;
pub mod bar;
pub mod order;
pub mod tick;
pub mod user;
pub mod stage;
pub use eztrade_macro::DataTransferObject;
use anyhow::Result;
use bytes::Bytes;
use serde::{Deserialize, Serialize};

pub trait DataTransferObject:
    Serialize
    + for<'de> Deserialize<'de>
    + Sized
{
    /// 将 TickData 序列化为 JSON 字节数组
    fn to_json_bytes(&self) -> Result<Bytes>;
    /// 从 JSON 字节数组反序列化 TickData
    fn from_json_bytes(bytes: &Bytes) -> Result<Self>;
    /// 将 TickData 序列化为二进制字节数组 (使用 bincode)
    fn to_binary_bytes(&self) -> Result<Bytes>;
    /// 从二进制字节数组反序列化 TickData (使用 bincode)
    fn from_binary_bytes(bytes: &Bytes) -> Result<Self>;
}

/// 消息类型定义
/// 
/// 注意这里的定义需要和客户端对齐, 方便Bincode正反序列化
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub enum Message {
    Authority(user::Authority),       // 用户鉴权传递
    Notification(String),             // 通知消息
    Order(order::Order),              // 订单消息（包括下单反馈、订单查询等）
    TickData(tick::TickData),         // Tick数据
    BarData(),                        // Bar数据(需要自行根据交易情况合并?)
    OrderOperation(order::OrderOperation), // 指令消息(查询/撤单)
    QueryAccount(),                   // 账户信息查询
    Portfolio(user::Portfolio),       // 账户信息
}

impl Message {
    /// 将 Message 序列化为二进制字节数组 (使用 bincode)
    pub fn to_binary_bytes(&self) -> Result<Bytes> {
        let mut binary_data = bincode::serialize(self)?;
        let checksum = binary_data.iter().fold(0u8, |acc, &x| acc.wrapping_add(x));
        binary_data.push(checksum);
        Ok(Bytes::from(binary_data))
    }

    /// 从二进制字节数组反序列化 Message (使用 bincode)
    pub fn from_binary_bytes(bytes: &Bytes) -> Result<Self> {
        let deserialized: Self = bincode::deserialize(&bytes[..bytes.len()-1])?;
        let checksum = bytes.last().copied().unwrap_or(0);
        let calculated_checksum = bytes[..bytes.len()-1].iter().fold(0u8, |acc, &x| acc.wrapping_add(x));
        if checksum != calculated_checksum {
            return Err(anyhow::anyhow!("Checksum mismatch"));
        }
        Ok(deserialized)
    }

    /// 将 Message 序列化为 JSON 字节数组
    pub fn to_json_bytes(&self) -> Result<Bytes> {
        let json_string = serde_json::to_string(self)?;
        Ok(Bytes::from(json_string))
    }

    /// 从 JSON 字节数组反序列化 Message
    pub fn from_json_bytes(bytes: &Bytes) -> Result<Self> {
        let json_str = std::str::from_utf8(bytes)?;
        let message = serde_json::from_str(json_str)?;
        Ok(message)
    }
}
